from django.contrib.auth import login
from django.shortcuts import render, redirect
# Create your views here.
from QQLoginTool.QQtool import OAuthQQ
from django.http import HttpResponse, JsonResponse, HttpResponseForbidden
import logging, re
from django.urls import reverse
from django_redis import get_redis_connection

from django.views import View
from django.conf import settings
from meiduo_01.utils.response_code import RETCODE
from oauth.models import OAuthQQUser
from oauth.utils import generate_access_token, check_access_token
from users.models import User

logger = logging.getLogger('django')


class QQAuthUserView(View):
    """处理qq登录回调：oauth_callback"""

    def get(self, req):
        """处理qq登录回调的业务逻辑"""

        # 获取code
        code= req.GET.get('code')
        if not code:
            return HttpResponseForbidden('获取code失败')

        # 创建工具对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI)

        try:
            # 使用code获取access_token
            access_token = oauth.get_access_token(code)

            # 摄影access_token 获取openid
            openid = oauth.get_open_id(access_token)
        except Exception as e:
            logger.error(e)
            return HttpResponseForbidden('OAuth2.0认证失败')
        # 使用openid判断该qq用户是否绑定美多商城用户
        try:
            oauth_user = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # openid未绑定美多商城用户
            access_token_openid = generate_access_token(openid)
            context = {'access_token_openid': access_token_openid}
            return render(req, 'oauth_callback.html', context=context)

        else:  # openid已绑定美多商城用户: oauth_user.user 表示从qq登录模型类对象中找到对应的用户模型对象
            login(req, oauth_user.user)

            # # 重定向到首页
            # response = redirect(reverse('contents:index'))

            # 重定向到state: 从哪儿来qq登录完回哪儿去
            next = req.GET.get('state')
            response = redirect(next)

            # 将用户名写到cookie中
            response.set_cookie('username',oauth_user.user.username, max_age=3600 * 24 *15)

            # 响应qq登录的结果
            return response

    def post(self, req):
        """
        实现绑定用户的逻辑
        :param req:
        :return:
        """
        # 接收参数
        mobile = req.POST.get('mobile')
        password = req.POST.get('password')
        sms_code_client = req.POST.get('sms_code')
        access_token_openid = req.POST.get('access_token_openid')

        # 校验
        # 判断是否齐全
        if not all([mobile, password, sms_code_client]):
            return HttpResponseForbidden('缺少必传参数111')
        # 手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return HttpResponseForbidden('请输入正确的手机号')
        if not re.match(r'^[0-9a-zA-Z]{8,20}$', password):
            return HttpResponseForbidden('请输入8-20位密码')
        # 判断短信验证码是否一致
        # redis_conn = get_redis_connection(sms_code_client)
        redis_conn = get_redis_connection('verify_code')
        sms_code_server = redis_conn.get('sms_%s' % mobile)
        if sms_code_server is None:  # 过期了
            # return HttpResponse()
            return render(req, 'oauth_callback.html', {'sms_code_errmsg': '无效的短信验证码'})
        if sms_code_client != sms_code_server.decode():
            return render(req, 'oauth_callback.html', {'sms_code_errmsg': '短信验证码不正确'})

        # 判断openid是否有效
        openid = check_access_token(access_token_openid)
        if openid is None:
            return render(req, 'oauth_callback.html', {'openid_errmsg': 'openid已失效'})

        # 使用手机号查询对应的用户是否存在
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            # 如果手机号不存在，新建用户
            user = User.objects.create_user(username=mobile, mobile=mobile, password=password)
        else:
            # 如果手机号存在 校验密码
            if not user.check_password(password):
                return render(req, 'oauth_callback.html', {'account_errmsg': '账号或密码错误'})

        # 将用户绑定到openid
        try:
            oauth_qq_user = OAuthQQUser.objects.create(user=user, openid=openid)
        except Exception as e:
            logger.error(e)
            return render(req, 'oauth_callback.html', {'qq_login_errmsg': '绑定失败'})

        # 实现状态保持
        # openid已绑定美多商城用户：oauth_user.user表示从qq登录模型类对象中找到的用户模型类对象
        login(req, oauth_qq_user.user)

        # 重定向到state: 从哪儿来qq登录完回哪儿去
        next = req.GET.get('state')
        response = redirect(next)

        # cookies中写入用户名
        response.set_cookie('username', oauth_qq_user.user.username, 3600 * 24 * 15)

        # 返回响应
        return response


class QQAuthURLView(View):
    """提供qq登录扫码页面"""

    def get(self, req):

        # 接收next
        next = req.GET.get('next')

        # 创建工具对象
        # oauth = OAuthQQ(client_id='appid', client_secret='appkey', redirect_uri='回调地址', state=next)
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI, state=next)

        # 生成qq登录扫码链接地址
        login_url = oauth.get_qq_url()

        # 响应
        return JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'login_url': login_url})
